<template>
    <div class="chat-pop">
        <!--聊天界面-->
        <div class="chat-pop-content" ref="chatContent" v-on:scroll="scrollHandler">
            <div class="chat-list" ref="chatList">
                <div class="chat-item" v-for="(item, i) in chatList" :key="item.i">
                    <div class="left" v-if="item.sendFrom != 'CUSTOMER' || userInfo.id != item.userId">
                        <div class="chat-bg">
                            <div class="chat-content" v-if="item.type == 'TEXT'">
                                <!-- <Badge dot v-if="item.readFlag != 'Y' && item.sendFrom != 'CUSTOMER'"></Badge> -->
                                <span class="text">{{ item.content }}</span>
                            </div>
                            <div class="chat-content image-content" @click="onViewImage(item.content)" v-else>
                                <!-- <Badge dot v-if="item.readFlag != 'Y' && item.sendFrom != 'CUSTOMER'"></Badge> -->
                                <img class="image" :src="getImageUrl(item.content)" alt="">
                            </div>
                            <span class="date">{{ item.createTime }}</span>
                        </div>
                    </div>
                    <div class="right" v-else>
                        <div class="chat-bg my-chat">
                            <div class="chat-content" v-if="item.type == 'TEXT'">
                                <span class="text">{{ item.content }}</span>
                            </div>
                            <div class="chat-content image-content" @click="onViewImage(item.content)" v-else>
                                <img class="image" :src="getImageUrl(item.content)" alt="">
                            </div>
                            <span class="date">{{ item.createTime }}</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="chat-loading" v-if="moreLoading && loading">
                <t-loading></t-loading>
            </div>
        </div>
        <div class="chat-pop-footer">
            <Input :border="false" @on-keyup="keySearch" v-model="chatContent" size="large"
                :placeholder="$t('user.enterContent')">
            </Input>
            <div class="camera-icon">
                <Upload :show-upload-list="false" :headers="{
                    'X-Access-Token': userToken,
                    'lang': 'en_US'
                }" biz="chat" :data="{
                    biz: 'chat'
                }" name="file" :before-upload="handleBeforeUpload" :on-progress="onProgress" :on-success="onSuccess"
                    :on-error="onError" :action="uploadURL">
                    <div class="loading-wrap" v-if="uploadLoading">
                        <t-loading></t-loading>
                    </div>
                    <Icon type="ios-camera" size="24" color="#fff" />
                </Upload>
            </div>
        </div>

        <Modal :title="$t('user.viewPicture')" v-model="visible">
            <img :src="viewImage" v-if="visible" style="width: 100%">
        </Modal>
    </div>
</template>

<script>
import { chatLogList, isRead, chatLogSpeak } from "@/api/chatLog";
import { mapState } from "vuex";
import { commonUpload } from "@/api/sys";
import TLoading from "@/components/t-loading";
import CeWebsocketUtil from "@/common/ce-websocket-util.js"
import dayjs from 'dayjs';

export default {
    name: "chat-pop",
    components: { TLoading },
    props: {
        orderId: [String, Number]
    },
    data() {
        return {
            domainURL: process.env.VUE_APP_GLOB_DOMAIN_URL,
            cdnURL:process.env.VUE_APP_CDN_URL_PREFIX,
            ws: null,
            wsBaseUrl: process.env.VUE_APP_WS_URL,
            socket: null,
            manualClose: false, // 是否手动关闭ws
            intervalId: null,
            timestamp: null,
            loading: true,
            viewImage: '',
            visible: false,
            form: {
                pageNo: 1,
                pageSize: 5
            },
            moreLoading: false,
            totalPage: 1,
            moreChat: true,
            uploadLoading: false, // 上传图片
            chatList: [], // 聊天记录列表
            chatContent: '', // 发送内容
            orderNo: this.orderId, // 订单号
            chatPop: true, // 聊天弹窗
            uploadURL: commonUpload(),
            userToken: localStorage.getItem('USER_TOKEN'),
            loadingTime: true,
        }
    },
    created() {
        this.getChatLogList();
        this.initWebSocket()
        // 启动ws
        // this.ws = new CeWebsocketUtil(this);
        // const URL = `ws://*****`;
        // this.ws.initWebsocket(URL);

    },
    computed: {
        ...mapState({
            userInfo: state => state.user.userInfo
        })
    },
    methods: {
        getImageUrl(url) {
            return url.startsWith('http') ? url : this.cdnURL + url
        },
        initWebSocket() {
            const that = this
            this.socket = new WebSocket(`${this.wsBaseUrl}/websocket/${this.userInfo.id}/order-msg/web`, this.userToken);
            // 当WebSocket打开时触发
            this.socket.addEventListener('open', function (event) {
                console.log('WebSocket 连接已打开');
            });
            // 当WebSocket接收到服务器发送的消息时触发
            this.socket.addEventListener('message', (event) => {
                console.log('收到消息: ' + event.data);
                const { orderMsg, action } = JSON.parse(event.data);
                if (orderMsg) {
                    orderMsg.createTime = dayjs(orderMsg.createTime).format('YYYY-MM-DD HH:mm:ss');
                }
                if (action === 'RESPONSE_SEND_TO_CUSTOMER_SERVICE') {
                    that.chatList.push({ ...orderMsg });
                } else {
                    that.chatList.push({ ...orderMsg, readFlag: 'N' });
                }
                // 有消息&&高度变化
                if (that.chatList.length > 0) {
                    that.scrollToBottom()
                }
            });
            // 当WebSocket出现错误时触发
            this.socket.addEventListener('error', function (event) {
                console.error('WebSocket 出现错误');
            });
            // 当WebSocket关闭时触发
            this.socket.addEventListener('close', function (event) {
                console.log('WebSocket 连接已关闭');
            });
        },
        sendMessage(type, content) {
            let msg = {
                action: 'SEND_TO_CUSTOMER_SERVICE',
                msg: {
                    orderNo: this.orderId,
                    type,
                    content
                }
            }
            if (this.socket.readyState === WebSocket.OPEN) {
                this.socket.send(JSON.stringify(msg));
                this.chatContent = '';
                this.uploadLoading = false;
                console.log('sendMessage: ', msg);
                this.newgGetChatLogList();
                this.scrollToBottom()
            } else {
                console.error('WebSocket 连接没有打开');
            }
        },
        onWsOpen() {
            console.log('websocket已连接成功');
            this.manualClose = false;
        },
        onViewImage(image) {
            this.visible = true;
            this.viewImage = image;
        },
        keySearch(typeKey) {
            if (typeKey.key == 'Enter' && this.chatContent.trim()) {
                this.sendMessage('TEXT', this.chatContent)
                // this.onChatLogSpeak('TEXT', this.chatContent);
            }
        },
        scrollHandler(event) {
            if (this.$refs.chatContent.scrollTop <= 30) {
                this.handleReachTop();
            }
        },
        // 是否已读
        isReadFlag(data) {
            data.map((item) => {
                if (item.readFlag != 'Y' && item.sendFrom == 'CUSTOMER_SERVICE') isRead(item.id)
            })
        },
        handleReachTop() {
            if (!this.moreChat) {
                return false;
            }
            if (this.moreLoading) {
                return false;
            }
            this.moreLoading = true;
            chatLogList({ orderNo: this.orderNo, ...this.form }).then((res) => {
                let data = res.result.records;
                this.isReadFlag(data);
                if (this.form.pageNo >= res.result.pages) {
                    this.moreChat = false;
                } else {
                    this.form.pageNo = this.form.pageNo + 1;
                }
                for (let i = 0; i < data.length; i++) {
                    this.chatList.unshift(data[i]);
                }
                this.moreLoading = false;
            }).catch(() => {
                this.moreLoading = false;
            })

        },
        onProgress(event, file, fileList) {
            // console.log('上传的钩子',event, file, fileList)
        },
        handleMaxSize(file) {
            this.$Message.error(`File ${file.name} is too large, no more than 100KB.`);
        },
        onSuccess(response) {
            // 上传成功
            this.uploadLoading = false;
            if (response.code == 0 || response.code == 200 || response.code == 201) {
                this.sendMessage('IMG', response.message)
                this.newgGetChatLogList()
                // this.onChatLogSpeak('IMG', response.message);
                this.$nextTick(() => {
                    this.scrollToBottom()
                })
            } else {
                this.$Message.error(response.message);
            }
        },
        onError(error, file) {
            this.uploadLoading = false;
            this.$Message.error(this.$t('user.uploadFailure'));
        },
        handleBeforeUpload(file) {
            this.uploadLoading = true;
        },
        scrollToBottom() {
            setTimeout(() => {
                let maxHeight = this.$refs.chatList.scrollHeight;
                this.$refs.chatContent.scrollTop = maxHeight;
            }, 100)
        },
        getChatLogList() {
            // 聊天记录
            this.moreChat = true;
            this.moreLoading = true;
            this.form.pageNo = 1;
            chatLogList({ orderNo: this.orderNo, ...this.form }).then((res) => {
                this.chatList = [];
                let data = res.result.records;
                this.isReadFlag(data);
                if (this.form.pageNo >= res.result.pages) {
                    this.moreChat = false;
                } else {
                    this.form.pageNo = this.form.pageNo + 1;
                }
                for (let i = 0; i < data.length; i++) {
                    this.chatList.unshift(data[i]);
                }
                this.loading = false;
                this.timestamp = res.timestamp
                // if (!this.intervalId) {
                //     this.intervalId = setInterval(() => {
                //         this.newgGetChatLogList()
                //     }, 5000)
                // }
                this.scrollToBottom();
                this.moreLoading = false;
            }).catch(() => {
                this.moreLoading = false;
            })
        },
        // 轮询获取最新消息
        newgGetChatLogList() {
            if (!this.loadingTime) return
            this.loadingTime = false
            const createTimeStart = dayjs(this.timestamp).format('YYYY-MM-DD HH:mm:ss');
            chatLogList({ orderNo: this.orderNo, createTimeStart }).then((res) => {
                this.loadingTime = true
                let data = res.result;
                if (data.length > 0) this.timestamp = res.timestamp
                this.isReadFlag(data);
                for (let i = 0; i < data.length; i++) {
                    let exists = this.chatList.some(targetItem => targetItem.id === data[i].id);
                    if (!exists) {
                        this.chatList.push(data[i]);
                    }
                }
            }).catch(() => {
            })
        },
        onChatLogSpeak(type, content) {
            // 聊天
            chatLogSpeak({
                orderNo: this.orderNo,
                type: type,
                content: content
            }).then((res) => {
                this.chatContent = '';
                this.uploadLoading = false;
                this.$Message.success(this.$t('user.send'));
                this.newgGetChatLogList();
                this.scrollToBottom()
            }).catch(() => {
                this.uploadLoading = false;
            })
        },
        // 关闭聊天
        upClose() {
            if (this.intervalId) clearInterval(this.intervalId);
            if (this.ws) {
                this.manualClose = true;
                this.ws.closeWebsocket();
            }
        }
    }
}
</script>

<style scoped lang="less">
.chat-pop {
    .chat-pop-content {
        position: relative;
        padding: 16px;
        height: 300px;
        overflow: auto;

        .chat-loading {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .chat-list {
            .chat-item {
                .left {
                    display: flex;

                    .chat-bg {
                        text-align: left;
                    }
                }

                .right {
                    display: flex;
                    justify-content: flex-end;
                }

                .chat-bg {
                    text-align: right;

                    .chat-content {
                        position: relative;
                        display: inline-block;
                        background: @t-table-border-color;
                        padding: 12px;
                        border-radius: 6px;
                        margin-top: 12px;

                        .ivu-badge {
                            position: absolute;
                            right: 0;
                            top: 0;
                        }

                        .text {
                            color: @t-title-color;
                            font-size: 14px;
                        }

                        .image {
                            display: block;
                            width: 120px;
                        }
                    }

                    .image-content {
                        padding: 0;
                        overflow: hidden;
                    }

                    .date {
                        display: block;
                        color: @t-text-color;
                        font-size: 12px;
                    }
                }

                .my-chat {
                    .chat-content {
                        background: @primary-color;

                        .text {
                            color: #ffffff;
                        }
                    }
                }
            }
        }
    }

    .chat-pop-footer {
        display: flex;
        align-items: center;
        padding: 12px 16px;
        border-top: 1px solid #e8eaec;

        .camera-icon {
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-left: 12px;
            flex: 0 0 32px;
            width: 32px;
            height: 32px;
            border-radius: 88px;
            background: @primary-color;

            .upload-image {
                cursor: pointer;
                width: 24px;
            }

            .loading-wrap {
                position: absolute;
                left: 0;
                right: 0;
                bottom: 0;
                top: 0;
                z-index: 999;
                display: flex;
                align-items: center;
                justify-content: center;

                .demo-spin-icon-load {
                    animation: ani-demo-spin 1s linear infinite;
                }

                @keyframes ani-demo-spin {
                    from {
                        transform: rotate(0deg);
                    }

                    50% {
                        transform: rotate(180deg);
                    }

                    to {
                        transform: rotate(360deg);
                    }
                }

                .demo-spin-col {
                    height: 100px;
                    position: relative;
                    border: 1px solid #eee;
                }
            }
        }
    }
}
</style>